#include "data.h"
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;

Data::Data(byte *bytes, byte len, string type)
{
	data = bytes;
	this->len = len;
	this->type = type;
}

Data::Data(string data)
{
	this->data = (new byte[data.size()]);
	len = data.length();
	memcpy(this->data, &data, len);
	type = "char";
}

Data::Data(int data)
{
	this->data = new byte[sizeof(int)];
	len = sizeof(int);
	memcpy(this->data, &data, len);
	type = "int";
}

Data::Data(float data)
{
	this->data = new byte[sizeof(float)];
	len = sizeof(float);
	memcpy(this->data, &data, len);
	type = "float";
}

Data::Data(const Data &d)
{
	len = d.len;
	type = d.type;
	data = new byte[len];
	memcpy(data, d.data, len);
}

const Data& Data::operator = (const Data &d)
{
	len = d.len;
	type = d.type;
	data = new byte[len];
	memcpy(data, d.data, len);
	return *this;
}

Data::~Data()
{
	delete data;
}

bool Data::operator < (const Data &d) const
{
	assert(type == d.type);
	if (type == "int")
		return *(int *)data < *(int *)d.data;
	else if (type == "char")
		return string((char *)data, len) < string((char *)d.data, d.len);
	else if (type == "float")
		return *(float *)data < *(float *)d.data;
	return false;
}

bool Data::operator >(const Data &d) const
{
	assert(type == d.type);
	if (type == "int")
		return *(int *)data > *(int *)d.data;
	else if (type == "char")
		return string((char *)data, len) > string((char *)d.data, d.len);
	else if (type == "float")
		return *(float *)data > *(float *)d.data;
	return false;
}

bool Data::operator == (const Data &d) const
{
	assert(type == d.type);
	if (type == "int")
		return *(int *)data == *(int *)d.data;
	else if (type == "char")
		return string((char *)data, len) == string((char *)d.data, d.len);
	else if (type == "float")
		return *(float *)data == *(float *)d.data;
	return false;
}

bool Data::operator <= (const Data &d) const
{
	assert(type == d.type);
	return !(*this > d);
}

bool Data::operator >= (const Data &d) const
{
	assert(type == d.type);
	return !(*this < d);
}

bool Data::operator != (const Data &d) const
{
	assert(type == d.type);
	return !(*this == d);
}

ostream& operator<<(ostream& cout, const Data& d)
{
	if (d.type == "char")
		cout << string((const char *)d.data, d.len);
	if (d.type == "int")
		cout << *(int *)d.data;
	if (d.type == "float")
		cout << *(float *)d.data;
	return cout;
}

